package ModeloLogicoSistema;

import ModeloLogicoSistema.Servicio.TipoServicio;
import com.itextpdf.text.DocumentException;
import java.io.IOException;
import java.sql.SQLException;
import java.util.ArrayList;
import java.util.Collections;
import java.util.List;
import java.util.ListIterator;
import java.util.logging.Level;
import java.util.logging.Logger;
import manejoDB.AdministradorDBOrden;

/**
 *
 * @author Veko
 */
public class AdministradorOrden {

    private AdministradorDBOrden consultadorDB;
    private List<Orden> ordenes;
    private List<ServicioContratado> servicios;

    public AdministradorOrden() throws SQLException {
        this.consultadorDB = new AdministradorDBOrden();
        ordenes = new ArrayList<>();
        this.consultadorDB.Conectar();
    }
    
    public List<Orden> cargarTodasLasOrdenes() throws SQLException{
         return this.cargarListaOrdenes(consultadorDB.getAllCodOrdenes());
    }
    
    /**
     *
     * @param los servicios cargados a la orden
     * @return Cliente
     * @see Carga la orden en la base de datos
     */
    
    
    public void persistirOrden(Integer codCliente, String fechaHoraPedido,
            String fechaPactada, String horaPactadaDesde, String horaPactadaHasta,
            Double montoTotal, Double montoAbonado,
            Double montoAdeudado,Double descuento, boolean delivery, String horaPedido,String observaciones) throws SQLException {
        /*String estado=EstadoOrden.PENDIENTE.toString();
        this.consultadorDB.setNuevaOrden(codCliente, fechaHoraPedido, fechaPactada,
                horaPactadaDesde,horaPactadaHasta,estado,montoTotal, montoAbonado, 
                montoAdeudado, delivery);*/
        this.consultadorDB.setNuevaOrden(codCliente, fechaHoraPedido, fechaPactada,
                horaPactadaDesde,horaPactadaHasta,EstadoOrden.PENDIENTE.toString(),montoTotal, montoAbonado, 
                montoAdeudado,descuento, delivery, horaPedido,observaciones);
    }
    
    public void persistirServicioDeOrden(Integer codOrden, Servicio servicio, Integer cantidad) throws SQLException{
        this.consultadorDB.setServicioOrden(servicio.getCodServicio(),codOrden,servicio.getPrecio(),cantidad,servicio.getPrecioProveedor());
    }
    
    

    
    public ServicioContratado cargarServicioContratado(Integer codServ,Integer codOrden){
        ServicioContratado servicio= null;
        try {
            servicio =new ServicioContratado(codServ, codOrden);
            servicio.setNombre(consultadorDB.getNombreServicio(codServ));
            servicio.setPrecio(consultadorDB.getPrecioEnServOrden(codServ, codOrden));
            servicio.setCantidad(consultadorDB.getCantEnServOrden(codServ,codOrden));
        }
        catch(Exception e){
            
        }
        return servicio;
    }
    
    public List<ServicioContratado> mostrarTodosLosServiciosContratados(Integer codOrden) throws SQLException{
        return cargarListaServiciosContratados(this.consultadorDB.getAllCodServicios(codOrden),codOrden);
    }
    
    public ArrayList<ServicioContratado> mostrarServiciosPlanchadoPendiente(Integer codOrden) throws SQLException{
        return (ArrayList)cargarListaServiciosContratados(this.consultadorDB.getPlanchados(codOrden,TipoServicio.Planchado.toString()),codOrden);
    }
    
    
    public List<ServicioContratado> mostrarTodosLosServiciosEspContratados(Integer codOrden) throws SQLException{
        return cargarListaServiciosEspContratados(this.consultadorDB.getAllCodServiciosEsp(codOrden),codOrden);
    }
    
    public List<Orden> mostrarTodasLasOrdenes() throws SQLException{
        return cargarListaOrdenes(this.consultadorDB.getAllCodOrdenes());
    }
    public Double getMontoTotal(List<Servicio> servicios) {
        ListIterator it = servicios.listIterator();
        Double suma = new Double(0);
        while (it.hasNext()) {
            Servicio servicio;
            servicio = (Servicio) it.next();
            suma = +servicio.getPrecio();
        }
        return suma;
    }
/*
    public Double getMontoTotal(Integer codigoOrden) throws SQLException {
        List <Double> precios= this.consultadorDB.getPrecioServicios(codigoOrden);
        ListIterator it = precios.listIterator();
        Double suma = new Double(0);
        while (it.hasNext()) {
            Double precio = (Double) it.next();
            suma = +precio;
        }
        return suma;
    }
*/
    
    /*
    public Double getMontoAdeudado(Double montoTotal, Double montoAbonado) {
        return montoTotal - montoAbonado;
    }*/

    /**
     * Obtiene un nuevo número de orden de una secuencia
     */
    public Integer nuevoCodigoOrden() throws SQLException {
        return this.consultadorDB.getNuevoCodigoOrden();
    }

    public Orden cargarOrden(Integer codigoOrden) {
        Orden orden = null;
        try {
            orden =new Orden(codigoOrden);
            orden.setCodCliente(consultadorDB.getCodCliente(codigoOrden));
            orden.setFechaHoraPedido(consultadorDB.getFechaPedido(codigoOrden),consultadorDB.getHoraPedido(codigoOrden));
            orden.setFechaPactada(consultadorDB.getFechaPactada(codigoOrden));
            orden.setEntrega(consultadorDB.getFechaEntrega(codigoOrden));
            orden.setHoraPactadaDesde(consultadorDB.getHoraPactadaDesde(codigoOrden));
            orden.setHoraPactadaHasta(consultadorDB.getHoraPactadaHasta(codigoOrden));
            orden.setSituacionOrden(consultadorDB.getEstadoOrden(codigoOrden));
            orden.setTotalMonto(consultadorDB.getMontoTotal(codigoOrden));
            orden.setMontoAbonado(consultadorDB.getMontoAbonado(codigoOrden));
            orden.setMontoAdeudado(consultadorDB.getMontoAdeudado(codigoOrden));
            orden.setDelivery(consultadorDB.getDelivery(codigoOrden));
            orden.setLugarAlmacenaje(consultadorDB.getLugarDeAlmacenajePedidoListo(EstadoOrden.LISTA.toString(),codigoOrden));
            orden.setObservaciones(consultadorDB.getObservaciones(codigoOrden));
            orden.setFechaListo(consultadorDB.getFechaListo(codigoOrden));
            orden.setHoraEntrega(consultadorDB.getHoraEntrega(codigoOrden));
            orden.setHoraListo(consultadorDB.getHoraListo(codigoOrden));
            orden.setDescuento(consultadorDB.getDescuento(codigoOrden));
        } catch (Exception ex) {
        }
        return orden;
    }

    public List<Orden> cargarListaOrdenes(List<Integer> codigosOrdenes) {
        List<Orden> ordenesParaMostrar = new ArrayList<>();
        ListIterator it = codigosOrdenes.listIterator();
        while (it.hasNext()) {
            Orden orden = cargarOrden((Integer) it.next());
            ordenesParaMostrar.add(orden);
        }
        return ordenesParaMostrar;
    }

    /**
     *
     * @see Métodos para buscar datos de ordenes
     */
    public List<Orden> buscarOrdenesPendientes() {
        try {
            return cargarListaOrdenes(consultadorDB.getOrdenesPorEstado(EstadoOrden.PENDIENTE.toString()));
        } catch (SQLException ex) {
            return new ArrayList<Orden>();
        }
    }

    public List<Orden> buscarOrdenesRealizadas() {
        try {
            return cargarListaOrdenes(consultadorDB.getOrdenesPorEstado(EstadoOrden.LISTA.toString()));
        } catch (SQLException ex) {
            return new ArrayList<Orden>();
        }
    }
    
    public List<Orden> buscarOrdenesEntregadasElDia(String fecha){
        try {
            return cargarListaOrdenes(consultadorDB.getOrdenesEntregadasElDia(EstadoOrden.ENTREGADA.toString(),fecha));
        } catch (SQLException ex) {
            return new ArrayList<Orden>();
        }
    }
    
    public List<Orden> buscarOrdenesRealizadasElDIA(String fecha) {
        try {
            return cargarListaOrdenes(consultadorDB.getOrdenesRealizadasElDia(fecha));
        } catch (Exception ex) {
            return new ArrayList<Orden>();
        }
    }
    
    
    public List<Orden> buscarOrdenesCreadasElDIA(String fecha) {
        try {
            return cargarListaOrdenes(consultadorDB.getOrdenesCreadasElDia(fecha));
        } catch (Exception ex) {
            return new ArrayList<Orden>();
        }
    }

    public List<Orden> buscarOrdenesPorCliente(Integer codCliente) {
        try {
            return cargarListaOrdenes(consultadorDB.getOrdenesPorCliente(codCliente));
        } catch (SQLException ex) {
            return null;
        }
    }

    /**
     *
     * Anular una orden
     */
    public void anularOrden(Integer codigoOrden) {
        try {
            consultadorDB.ModificarEstado(EstadoOrden.ANULADA.toString(), codigoOrden);
        } catch (SQLException ex) {
        }
    }

    private List<ServicioContratado> cargarListaServiciosContratados(List<Integer> allCodServicios,Integer codOrden) {
        ListIterator it=allCodServicios.listIterator();
        ArrayList<ServicioContratado> lista=new ArrayList();
        while(it.hasNext()){
            Integer codS=(Integer)it.next();
            ServicioContratado serv=this.cargarServicioContratado(codS, codOrden);
            lista.add(serv);
        }
        return lista;
    }

    public void persistirServEspDeOrden(ServicioEspecialContratado servEsp) throws SQLException {
        this.consultadorDB.setServicioEspecial(servEsp.getCodorden(), servEsp.getNombre(), servEsp.getPrecio(), servEsp.getCantidad(), servEsp.getTipo());
    }

    public int getCantPendientes(String fechaEntrega, String tipoServicio) throws SQLException {
        return this.consultadorDB.getCantPendientesPorEstado(fechaEntrega, EstadoOrden.PENDIENTE.toString(), tipoServicio);
    }

    public int getCantDeliverysPendientesParaDia(String fechaEntrega) throws SQLException {
        return this.consultadorDB.getCantDeliverysPendientes(fechaEntrega, EstadoOrden.ENTREGADA.toString(), EstadoOrden.ANULADA.toString());
    }
    
    public void setLugarAlmacenaje(String almacenaje, Integer codOrden) throws SQLException {
        this.consultadorDB.ModificarLugarAlmacenajePedidoListo(almacenaje, codOrden);
    }

    public void modificarEstado(String estado, Integer codOrden) throws SQLException {
        this.consultadorDB.ModificarEstado(estado, codOrden);
    }

    public void setFechaEntrega(String fechaEntrega,Integer idOrden) throws SQLException {
        this.consultadorDB.ModificarFechaEntrega(fechaEntrega, idOrden);
    }

    public void setFechaEntregaPautada(String fechaPautada, Integer codOrden) throws SQLException {
        this.consultadorDB.ModificarFechaEntregaPactada(fechaPautada, codOrden);
    }

    private List<ServicioContratado> cargarListaServiciosEspContratados(List<Integer> allCodServiciosEsp, Integer codOrden) {
        ListIterator it=allCodServiciosEsp.listIterator();
        ArrayList<ServicioContratado> lista=new ArrayList();
        while(it.hasNext()){
            Integer codS=(Integer)it.next();
            ServicioContratado serv=this.cargarServicioEspContratado(codS, codOrden);
            lista.add(serv);
        }
        return lista;
    
    }

    private ServicioContratado cargarServicioEspContratado(Integer codS, Integer codOrden) {
        ServicioContratado servicio= null;
        try {
            servicio =new ServicioContratado(codS, codOrden);
            servicio.setNombre(consultadorDB.getNombreServicioEsp(codS));
            servicio.setPrecio(consultadorDB.getPrecioEnServOrdenEsp(codS, codOrden));
            servicio.setCantidad(consultadorDB.getCantEnServOrdenEsp(codS,codOrden));
        }
        catch(Exception e){
            
        }
        return servicio;
    
    }

    public ArrayList<Orden> buscarOrdenesListasPautadasPara(String fechaPactada) {
        try {
            return (ArrayList)cargarListaOrdenes(consultadorDB.getOrdenesPorEstadoPautadasPara(EstadoOrden.LISTA.toString(),fechaPactada));
        } catch (SQLException ex) {
            return new ArrayList<>();
        }
    }

    public ArrayList<Orden> buscarOrdenesPendientesPautadasPara(String fechaPactada) {
        try {
            return (ArrayList)cargarListaOrdenes(consultadorDB.getOrdenesPorEstadoPautadasPara(EstadoOrden.PENDIENTE.toString(),fechaPactada));
        } catch (SQLException ex) {
            return new ArrayList<>();
        }
    }
    
    public ArrayList<Orden> listadoOrdenadoPorDelivery(String fechaPactada){
        ArrayList<Orden> ordenes=new ArrayList();
        Collections.sort(ordenes, new ComparaDelivery());
        try {
            ordenes=(ArrayList)cargarListaOrdenes(consultadorDB.getOrdenesConDeliveryPorFechaPautada(fechaPactada));
        } catch (SQLException ex) {
            Logger.getLogger(AdministradorOrden.class.getName()).log(Level.SEVERE, null, ex);
        }
        return ordenes;
    }

    public void setFechaListo(String fechaNueva, Integer codOrden) throws SQLException {
        this.consultadorDB.agregarFechaListo(fechaNueva, codOrden);
    }

    public Integer getCantValetsPendientesXorden(Integer cod) throws SQLException {
        return this.consultadorDB.getCantPendientesDeOrdenXTipo(EstadoOrden.PENDIENTE.toString(),TipoServicio.Valets.toString(),cod);
    }

    public int getCantPlanchadosPendientesXorden(Integer codOrden) throws SQLException {
        
        return this.consultadorDB.getCantPendientesDeOrdenXTipo(EstadoOrden.PENDIENTE.toString(),TipoServicio.Planchado.toString(),codOrden);
    }

    public ArrayList<Orden> buscarOrdenesEntregadasPautadasParaDia(String fecha) throws SQLException {
        return (ArrayList)cargarListaOrdenes(consultadorDB.getOrdenesEntregadasPautadasPara(EstadoOrden.ENTREGADA.toString(),fecha));
    }

    public ArrayList<Orden> buscarOrdenesEntregadasEntreLosDias(String fechaI, String fechaF) throws SQLException {
        return (ArrayList<Orden>) cargarListaOrdenes(consultadorDB.getOrdenesEntregadasEntre(EstadoOrden.ENTREGADA.toString(),fechaI,fechaF));
    }

    public Double getCostoTercerizados(Integer codOrden) throws SQLException {
        return this.consultadorDB.getCostoT(codOrden);
    }

    public void setHoraListo(String horaListo, Integer codOrden) throws SQLException {
        this.consultadorDB.agregarHoraListo(horaListo, codOrden);
    }

    public void setNuevaHoraPautadaD(Integer codOrden, String horaDesde) throws SQLException {
        this.consultadorDB.ModificarHoraPactadaDesde(horaDesde, codOrden);
    }

    public void setNuevaHoraPautadaH(Integer codOrden, String horaHasta) throws SQLException {
        this.consultadorDB.ModificarHoraPactadaHasta(horaHasta, codOrden);
    }

    public void setHoraEntrega(String horaActual, Integer codOrden) throws SQLException {
        this.consultadorDB.setHoraEntrega(horaActual, codOrden);
    }

    public void setDelivery(Integer codOrden, boolean delivery) throws SQLException {
        this.consultadorDB.setDelivery(delivery, codOrden);
    }

    ArrayList<Orden> ordenesPlanchadoPendiente(String fechaPautada) throws SQLException {
        return (ArrayList)cargarListaOrdenes(this.consultadorDB.ordenesPendiente(EstadoOrden.PENDIENTE.toString(),fechaPautada));
    }
}

